<template>
  <div>
    <!-- <h1>SKU管理</h1> -->
    <el-card>
      <el-table border style="margin: 10px 0px;" :data="skuList">
        <el-column type="index" width="80px" label="序号" align="center"></el-column>
        <!-- 注：属性“show-overflow-tooltip”被用于“当内容过长被隐藏时显示提示框”↓ -->
        <el-table-column align="center" label="名称" show-overflow-tooltip width="150px" prop="skuName"></el-table-column>
        <el-table-column align="center" label="描述" show-overflow-tooltip width="150px" prop="skuDesc"></el-table-column>
        <el-table-column align="center" label="图片" width="150px">
          <!-- 作用域插槽↓ -->
          <template #default="{ row, $index }">
            <img :src="row.skuDefaultImg" alt="图片地址已失效" style="width: 100px; height: 100px;" />
          </template>
        </el-table-column>
        <el-table-column align="center" label="重量（克）" width="150px" prop="weight"></el-table-column>
        <el-table-column align="center" label="价格（元）" width="150px" prop="price"></el-table-column>
        <!-- 注：固定列需要使用 fixed 属性，它接受 Boolean 值。 如果为 true, 列将被左侧固定。 它还接受传入字符串，left 或 right，表示左边固定还是右边固定↓ -->
        <el-table-column align="center" label="操作" width="380px" fixed="right">
          <template #default="{ row, $index }">
            <!-- <el-button type="info" size="small" icon="Top"></el-button> -->
            <!-- 注：“row.isSale==1”表示“当前商品已上架，正在售卖”，图标应为“向下的箭头”（即“Bottom”（表示“可以将它下架”））↓ -->
            <el-button type="info" size="small" :icon="row.isSale == 1 ? 'Bottom' : 'Top'"
              @click="switchThisSkuOnSaleOrNot(row)" v-haveThisButton="`btn.Sku.updown`"></el-button>
            <el-button type="primary" size="small" icon="Edit" @click="handlerForUpdateAnSku" v-haveThisButton="`btn.Sku.update`"></el-button>
            <el-button type="info" size="small" icon="infoFilled"
              @click="handlerForViewTheDetailInformationOfAnSku(row)" v-haveThisButton="`btn.Sku.detail`"></el-button>
            <el-popconfirm :title="`你确定删除${row.skuName}吗？`" width="200px"
              @confirm="handlerForUserClickTheConfirmButton(row.id)">
              <template #reference>
                <el-button type="danger" size="small" icon="Delete" v-haveThisButton="`btn.Sku.remove`"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器↓ -->
      <!-- 注：由于“current-change”事件会向其处理函数传递新的页码作为参数，所以此处可以直接以“getSkuList”作为“事件处理函数”↓ -->
      <!-- <el-pagination @current-change="handlerForChangeCurrentPageNumber" @size-change="handlerForChangeThePageSizeOfPaginationComponent" -->
      <el-pagination @current-change="getSkuList" @size-change="handlerForChangeThePageSizeOfPaginationComponent"
        v-model:current-page="currentPageNumber" v-model:page-size="currentPageSize" :page-sizes="[10, 20, 30, 40]"
        :background="true" layout="prev, pager, next, jumper,->,sizes,total" :total="totalNumberOfTheSku" />
      <!-- 抽屉组件（被用于展示商品（SKU）的详情）（注：属性“direction”被用于设置“抽屉打开的方向”（它可以接受四个值：rtl/ltr/ttb/btt（right to left、bottom to top等）。默认值为rtl））↓ -->
      <el-drawer v-model="isTheDrawerVisible" direction="rtl">
        <template #header>
          <h4>查看商品的详情</h4>
        </template>
        <template #default>
          <div>
            <!-- 用栅格系统为抽屉组件的主体部分做布局↓ -->
            <el-row style="margin: 10px 0px;">
              <el-col :span="6">名称</el-col>
              <!-- <el-col :span="18">mate20</el-col> -->
              <el-col :span="18">{{ theDetailInformationOfAnSku.skuName }}</el-col>
            </el-row>
            <el-row style="margin: 10px 0px;">
              <el-col :span="6">描述</el-col>
              <!-- <el-col :span="18">华为是中国著名的手机厂商</el-col> -->
              <el-col :span="18">{{ theDetailInformationOfAnSku.skuDesc }}</el-col>
            </el-row>
            <el-row style="margin: 10px 0px;">
              <el-col :span="6">价格</el-col>
              <!-- <el-col :span="18">6999元</el-col> -->
              <el-col :span="18">{{ theDetailInformationOfAnSku.price }}</el-col>
            </el-row>
            <el-row style="margin: 10px 0px;">
              <el-col :span="6">平台属性</el-col>
              <el-col :span="18">
                <!-- <el-tag v-for="item in 10" style="margin:5px;">{{ item }}</el-tag> -->
                <el-tag v-for="item in theDetailInformationOfAnSku.skuAttrValueList" style="margin:5px;"
                  :key="item.id">{{ item.valueName }}</el-tag>
              </el-col>
            </el-row>
            <el-row style="margin: 10px 0px;">
              <el-col :span="6">销售属性</el-col>
              <el-col :span="18">
                <!-- <el-tag v-for="item in 10" style="margin:5px;">{{ item }}</el-tag> -->
                <el-tag v-for="item in theDetailInformationOfAnSku.skuSaleAttrValueList" style="margin:5px;"
                  :key="item.id">{{ item.saleAttrValueName }}</el-tag>
              </el-col>
            </el-row>
            <el-row style="margin: 10px 0px;">
              <el-col :span="6">商品图片</el-col>
              <el-col :span="18">
                <!-- 轮播图（走马灯）组件↓ -->
                <el-carousel :interval="4000" type="card" height="200px">
                  <!-- <el-carousel-item v-for="item in 6" :key="item"> -->
                  <el-carousel-item v-for="item in theDetailInformationOfAnSku.skuImageList" :key="item.id">
                    <!-- <h3 text="2xl" justify="center">{{ item }}</h3> -->
                    <img :src="item.imgUrl" alt="图片地址已失效" style="width: 100%;height: 100%;" />
                  </el-carousel-item>
                </el-carousel>
              </el-col>
            </el-row>
          </div>
        </template>
      </el-drawer>
    </el-card>
  </div>
</template>

<script lang="ts" setup name="SKU">
import { ref, onMounted } from 'vue';
// 导入请求方法↓
import { requestSkuList, requestMakeAnSkuForSale, requestMakeAnSkuNotForSale, requestGetTheDtailInformationOfAnSku, requestDeleteAnSku } from "@/api/product/sku";
import type { typeOfResponseDataOfTheApiThatGetSkuList, typeOfObjectThatRepresentsAnSku, } from "@/api/product/sku/type";
import { ElMessage } from 'element-plus';
let currentPageNumber = ref<number>(1); // 当前页码
let currentPageSize = ref<number>(10); // 每页显示的数据条目数量
let totalNumberOfTheSku = ref<number>(0); // 总数据条目数量
let skuList = ref<typeOfObjectThatRepresentsAnSku[]>([]) // SKU列表
let isTheDrawerVisible = ref<boolean>(false); // 控制抽屉组件的显示与隐藏
// let theDetailInformationOfAnSku = ref<typeOfObjectThatRepresentsAnSku>({}); // 商品（SKU）的详细信息
// 注：由于服务器返回数据中的某些属性在类型“typeOfObjectThatRepresentsAnSku”中并未被定义，因此此处使用了“any”类型（为节省时间，暂时不到类型定义中去为缺失的属性补充数据类型了）↓
let theDetailInformationOfAnSku = ref<any>({}); // 商品（SKU）的详细信息
onMounted(() => {
  getSkuList(); // 调用获取SKU列表的方法
})
/**
 * @description：获取SKU列表的方法
 * @param pageNumber 当前页码（默认为1）
 */
async function getSkuList(pageNumber = 1) {
  currentPageNumber.value = pageNumber; // 更新当前页码
  let result: typeOfResponseDataOfTheApiThatGetSkuList = await requestSkuList(currentPageNumber.value, currentPageSize.value)
  console.log(result) // {code: 201, message: '失败', data: null, ok: false}
  if (result.code == 200) {
    /* 注：在此处，文心快码解释了“为什么‘result.data’的后面会出现感叹号”：在TypeScript中，感叹号（!）是一个非空断言操作符。这个操作符用于告诉TypeScript编译器，开发者确信某个表达式在运行时不会是null或undefined，即使TypeScript的类型检查可能表明它可能是null或undefined。^[1]^
      分析与思考：1.类型定义：在代码中，result被声明为typeOfResponseDataOfTheApiThatGetSkuList类型。这个类型可能定义在@/api/product/sku/type文件中。result.data的类型可能在该类型定义中被标记为可能是null或undefined。（但是实际情况不是这样的，实际情况是服务器有故障，导致属性“data”的值是null）
      2.API响应：根据console.log(result)的输出，result对象的data属性是null。如果result.data的类型确实包含null或undefined，那么在访问result.data.total时，TypeScript编译器会报错，因为它不能确定result.data在运行时不是null。
      3.非空断言操作符：使用result.data!告诉TypeScript编译器，您确信result.data不会是null或undefined，即使在类型定义中它可能是。这通常用于开发者确信某些条件（如API成功响应）下，某个属性不会是null或undefined的情况。
      回答：在您的代码中，result.data!后面的感叹号是一个非空断言操作符。它被用来告诉TypeScript编译器，尽管result.data的类型可能包含null或undefined，但您确信在当前的上下文中（即API响应成功时），result.data不会是null或undefined。这样，您就可以安全地访问result.data.total而不会引发TypeScript的类型错误。
      然而，需要注意的是，非空断言操作符应该谨慎使用，因为它会绕过TypeScript的类型检查。如果result.data在运行时实际上是null或undefined，那么访问result.data.total将会导致运行时错误。因此，在使用非空断言操作符之前，最好确保相关的条件确实成立。
      建议：1.检查API响应：确保API响应成功时result.data不会是null或undefined。2.类型安全：如果可能，修改类型定义以避免使用非空断言操作符，或者在使用之前进行适当的空值检查。↓ */
    totalNumberOfTheSku.value = result.data!.total; // 赋值总数据条目数量
    skuList.value = result.data!.records; // 为SKU列表赋值
  }
}
/**
 * @description 函数“handlerForChangeCurrentPageNumber”被用于处理“分页器当前页码被改变”时发生的事件
 * @param newPageNumber 新的页码
 */
/* function handlerForChangeCurrentPageNumber(newPageNumber:number) {
  console.log(newPageNumber) // 打印新的页码
  currentPageNumber.value = newPageNumber; // 更新当前页码
  getSkuList(newPageNumber); // 调用获取SKU列表的方法，并传入新的页码作为参数
} */
/**
 * @description 函数“handlerForChangeThePageSizeOfPaginationComponent”被用于处理“分页器当前每页可显示的数据条目数量被改变”时发生的事件
 * @param newPageSize 新的每页可显示的数据条目数量
 */
function handlerForChangeThePageSizeOfPaginationComponent(newPageSize: number) {
  console.log(newPageSize) // 打印新的每页可显示的数据条目数量
  getSkuList() // 调用获取SKU列表的方法，但不传入新的页码作为参数（因为改变”每页可显示的数据条目数量“时需要获取第一页的数据，此时直接使用“参数默认值”即可）
}
/**
 * @description 函数“switchThisSkuOnSaleOrNot”被用于处理点击“上架/下架按钮”时发生的事件（即切换SKU的售卖状态）
 * @param row 当前行的数据对象（即当前SKU对象）
 */
async function switchThisSkuOnSaleOrNot(row: typeOfObjectThatRepresentsAnSku) {
  if (row.isSale == 1) {
    // 注：如果进入了这个代码块，那么说明当前商品已上架，正在售卖
    let result = await requestMakeAnSkuNotForSale((row.id as number))
    console.log(result)
    try {
      ElMessage({
        type: 'success',
        message: '下架成功',
        center: true,
      })
    } catch (error) {
      ElMessage({
        type: 'error',
        message: '下架失败，请稍后再试',
        center: true,
      })
    }
    getSkuList(currentPageNumber.value) // 重新获取SKU列表，以便更新UI
  } else {
    // 进入此代码块则说明当前商品未上架，不在售卖中
    let anotherResult = await requestMakeAnSkuForSale((row.id as number))
    console.log(anotherResult) // {code: 200, message: '成功', data: null, ok: true}
    try {
      ElMessage({
        type: 'success',
        message: '上架成功',
        center: true,
      })
    } catch (error) {
      ElMessage({
        type: 'error',
        message: '上架失败，请稍后再试',
        center: true,
      })
    }
    getSkuList(currentPageNumber.value)
  }
}
/**
 * @description 函数“handlerForUpdateAnSku”被用于处理点击“编辑按钮”时发生的事件（即更新SKU）
 */
function handlerForUpdateAnSku() {
  ElMessage({
    type: 'info',
    message: '暂未实现该功能，敬请期待',
    center: true,
  })
}
/**
 * @description 函数“handlerForViewTheDetailInformationOfAnSku”被用于处理点击“查看按钮”时发生的事件（即查看SKU的详细信息）
 * @param row 当前行的数据对象（即当前SKU对象）
 */
async function handlerForViewTheDetailInformationOfAnSku(row: typeOfObjectThatRepresentsAnSku) {
  isTheDrawerVisible.value = true; // 显示抽屉组件
  // console.log(row) // 打印当前行的数据对象（即当前SKU对象）：Proxy(Object) {id: 296, createTime: '2025-03-15 12:24:01', updateTime: '2025-03-16 03:24:25', spuId: null, price: 2, …}
  // console.log(row.id) // 打印SKU的ID：296
  let result: typeOfObjectThatRepresentsAnSku = await requestGetTheDtailInformationOfAnSku(row.id as number)
  console.log(result) // 由于服务器出故障，目前的打印内容是undefined
  theDetailInformationOfAnSku.value = result.data; // 存储SKU的详细信息
}
/**
 * @description 函数“handlerForUserClickTheConfirmButton”被用于处理用户点击气泡确认框组件中的“确认按钮”时发生的事件（即删除SKU）
 * @param skuId SKU的ID
 */
async function handlerForUserClickTheConfirmButton(skuId: number) {
  // 请求删除SKU↓
  let result = await requestDeleteAnSku(skuId)
  console.log(result) // {code: 201, message: '失败', data: null, ok: false}
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: '删除成功',
      center: true,
    })
    // 注：删除成功后需要调用“getSkuList”方法来重新获取SKU列表，以便更新UI。如果删除这条数据后，当前页面剩余的数据条目数量大于1，那么就保持当前页码不变；如果删除这条数据后，当前页面剩余的数据条目数量小于1，那么就将当前页码减一（即跳转到上一页）↓
    getSkuList(skuList.value.length>1?currentPageNumber.value:currentPageNumber.value-1)
  } else {
    ElMessage({
      type: 'error',
      message: '删除失败，请稍后再试',
      center: true,
    })
  }
}
</script>

<style scoped>
.el-carousel__item h3 {
  color: #475669;
  opacity: 0.75;
  line-height: 200px;
  margin: 0;
  text-align: center;
}

.el-carousel__item:nth-child(2n) {
  background-color: #99a9bf;
}

.el-carousel__item:nth-child(2n + 1) {
  background-color: #d3dce6;
}
</style>